home *** CD-ROM | disk | FTP | other *** search
/ Ultimedia 2 / Ultimedia 2.iso / tools / animplayer / amipeg / source.lha / ham8.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-03  |  7.8 KB  |  344 lines

  1. /*
  2.  *  This source copes with all amiga-specific stuff as opening the screen, resizing
  3.  *  it using user copper lists, etc.
  4.  *
  5.  *  Copper-based resizing is now implemented, although no aspect ratio is taken care of.
  6.  *
  7.  *  Michael Rausch  14-2-94  12:00:00
  8.  */
  9.  
  10. #include <proto/exec.h>
  11. #include <proto/intuition.h>
  12. #include <proto/graphics.h>
  13.  
  14. #include <exec/memory.h>
  15. #include <hardware/custom.h>
  16. #include <graphics/copper.h>
  17. #include <graphics/gfxbase.h>
  18. #include <graphics/gfxmacros.h>
  19. #include <graphics/videocontrol.h>
  20. #include <graphics/displayinfo.h>
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25.  
  26. #include "video.h"
  27. #include "proto.h"
  28. extern int ditherType;
  29.  
  30. extern void HAM8_Init(struct RastPort *);    // kinda static
  31. extern void HAM8_Init_lores(struct RastPort *);
  32.  
  33. void (*HAM8_draw)(void *, int, int);
  34.  
  35.  
  36. #define custom ((*(volatile struct Custom *)(0xdff000)))
  37.  
  38.  
  39. struct IntuitionBase *IntuitionBase;
  40. struct GfxBase *GfxBase;
  41. extern struct ExecBase *SysBase;
  42. static struct Screen *screen;
  43. static ULONG soerror = NULL;
  44.  
  45. int gfx40;
  46. ULONG *kaiko = NULL;
  47.  
  48. int lores, sdbl;
  49.  
  50. int max_x, max_y;
  51.  
  52. static struct ColorSpec firstblack[2]={ {0,0,0,0}, {-1, 0,0,0} };    /* Color 0 is 0x000*/
  53.  
  54. /*static const ULONG colconv[4] = {0x0,0x55000000,0xaa000000,0xff000000};*/
  55.  
  56.  
  57. static void Quit(char *why, int failcode)
  58. {
  59.     puts(why);
  60.     exit(failcode);
  61. }
  62.  
  63. static void output_term(void)
  64. {
  65.     if (screen)
  66.     {
  67.         FreeVPortCopLists(&(screen->ViewPort));
  68.         RemakeDisplay();
  69.         CloseScreen(screen);
  70.     }
  71.     if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase);
  72.     if (GfxBase) CloseLibrary((struct Library *) GfxBase);
  73. }
  74.  
  75.  
  76. void InitColorDisplay(char *name)
  77. {
  78.     /*int i;
  79.     ULONG base[1+64*3+1];*/
  80.  
  81.     atexit(output_term);
  82.  
  83.     if ((GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",39))==NULL)
  84.         Quit("graphics.library is too old, <V39",25);
  85.     if ((IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",39))==NULL)
  86.         Quit("intuition.library is too old, <V39",25);
  87.  
  88.     gfx40 = GfxBase->LibNode.lib_Version >= 40;
  89.     if(gfx40) kaiko = GfxBase->ChunkyToPlanarPtr;
  90.  
  91.  
  92.     /*base[0] = 64 << 16;
  93.     for(i=1, j=0; j<64; j++)
  94.     {
  95.         base[i++] = colconv[(j>>0)&3];
  96.         base[i++] = colconv[(j>>4)&3];
  97.         base[i++] = colconv[(j>>2)&3];
  98.     }
  99.     base[i] = 0;*/
  100.  
  101.  
  102.     HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  103.     DoDitherImage = NoDitherImage;
  104.  
  105. }
  106.  
  107.  
  108. /*
  109.  *   Resize the display using a copper list. Nifty'n neat amiga feature.
  110.  *
  111.  *   Phew ... takes now 2 hours to fiddle the system-compliant custom modulo stuff.
  112.  */
  113. void ResizeDisplay(int w, int h)
  114. {
  115.     struct UCopList *ucoplist;
  116.     static struct TagItem uCopTags[] = {
  117.         { VTAG_USERCLIP_SET, NULL },
  118.         { VTAG_END_CM, NULL }};
  119.     int i,j,k, y, fp_each, locallores;
  120.     struct CopList *dspins;
  121.     struct CopIns *copins;
  122.     short bpl1mod=0, bpl2mod=0, last1, last2, this1, this2;
  123.     ULONG id;
  124.     struct DimensionInfo dim_info;
  125.  
  126.  
  127.     if (ditherType == NO_DITHER) return;
  128.  
  129.     id = BestModeID(TAG_END) & MONITOR_ID_MASK;    /* get default monitor */
  130.  
  131.     if (GetDisplayInfoData(FindDisplayInfo(id), (UBYTE *)&dim_info, sizeof(struct DimensionInfo), DTAG_DIMS, 0))
  132.         max_y=dim_info.StdOScan.MaxY - dim_info.StdOScan.MinY + 1;
  133.     else
  134.         max_y=200;
  135.  
  136.     sdbl=TRUE;
  137.     if(h>max_y)
  138.         sdbl=FALSE, max_y<<=1;
  139.  
  140.     lores=TRUE;
  141.     locallores = lores && (w<=160);
  142.  
  143.     switch(id)
  144.     {
  145.         case A2024_MONITOR_ID:
  146.             Quit("Get some colors, dude.", 25);
  147.  
  148.         case PAL_MONITOR_ID:
  149.         case NTSC_MONITOR_ID:
  150.             if(gfx40 && sdbl)
  151.                 id = locallores ? LORESHAMSDBL_KEY: HIRESHAMSDBL_KEY;
  152.             else
  153.                 sdbl=FALSE, id = locallores ? HAM_KEY : HIRESHAM_KEY;
  154.             break;
  155.  
  156.         case EURO72_MONITOR_ID:
  157.             if(sdbl)
  158.                 id = locallores ? EURO72LORESHAMDBL_KEY : EURO72PRODUCTHAMDBL_KEY;
  159.             else
  160.                 id = locallores ? EURO72LORESHAM_KEY : EURO72PRODUCTHAM_KEY;
  161.             break;
  162.  
  163.         default:
  164.             if(sdbl)
  165.                 id = locallores ? VGALORESHAMDBL_KEY : VGAPRODUCTHAMDBL_KEY;
  166.             else
  167.                 id = locallores ? VGALORESHAM_KEY : VGAPRODUCTHAM_KEY;
  168.             break;
  169.     }
  170.  
  171.     if(!(screen=OpenScreenTags(NULL,
  172.         SA_DisplayID,    id,
  173.         SA_Depth,    8,
  174.         SA_Width,    max_x = (locallores ? 320 : 640),
  175. //        SA_Colors32,    base,
  176.         SA_Colors,    firstblack,
  177.         SA_Type,    CUSTOMSCREEN,
  178.         SA_Quiet,     TRUE,
  179.         SA_Interleaved,    TRUE,
  180.         SA_Overscan,    OSCAN_STANDARD,
  181.         SA_MinimizeISG,    TRUE,
  182.         SA_ErrorCode,    &soerror,
  183.         TAG_END))) Quit("Couldn't open screen.",25);
  184.  
  185.     if(lores) {
  186.         HAM8_Init_lores(&(screen->RastPort));
  187.         HAM8_draw = HAM8_draw_lores;
  188.         DoDitherImage = ColorDitherImage_lores;    // lacks kaiko support, actually
  189.         max_x >>=1;
  190.     } else {
  191.         HAM8_Init(&(screen->RastPort));
  192.         HAM8_draw = HAM8_draw_hires;
  193.         DoDitherImage = ColorDitherImage;    // kaiko
  194.         max_x >>=2;
  195.     }
  196.  
  197.     if(noDisplayFlag)
  198.         HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  199.  
  200.  
  201.     /* the memory is freed upon exit in output_term via FreeVPortCopLists */
  202.     if(!(ucoplist = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR)))
  203.         Quit("No memory for copper list.",25);
  204.  
  205.     /* fiddle out some hardware values from this screen's init copper list */
  206.     dspins=screen->ViewPort.DspIns;
  207.     copins=dspins->CopIns;
  208.     for(i=dspins->Count-1; i>=0; i--, copins++)
  209.     {
  210.         j = copins->DESTDATA;
  211.         switch(copins->DESTADDR)
  212.         {        
  213.             case (int)&((*(struct Custom *)(0)).bpl1mod):
  214.                 last1=bpl1mod = j;
  215.                 break;
  216.             case (int)&((*(struct Custom *)(0)).bpl2mod):
  217.                 last2=bpl2mod = j;
  218.                 break;
  219.         }
  220.     }
  221.  
  222.     if(bpl1mod==0 || bpl2mod==0)    return;    /* hmmm? */
  223.  
  224.     if((bpl1mod == bpl2mod) && sdbl) sdbl=FALSE;
  225.  
  226.     y = screen->Height;
  227.     (void) CINIT(ucoplist, y*3);        /* ... instructions per line */
  228.  
  229.     if(sdbl)
  230.     {
  231.         /*
  232.          *  We abuse some of AGA's features here; double-scanning is implemented
  233.          *  by applying bpl1mod to ALL planes on one line, bpl2mod on the next.
  234.          *  Obviously, double-scanning enables some kind of internal chipmem cache.
  235.          *  At least, it's faster. And (because of?) less copper instructions.
  236.          */
  237.  
  238.         fp_each = ((y*2)<<8) / (short)h;
  239.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  240.         {
  241.  
  242.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  243.                 this1=bpl1mod;
  244.             else                        /* finally, we are ready; next one */
  245.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  246.  
  247.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  248.                 this2=bpl1mod;
  249.             else                        /* finally, we are ready; next one */
  250.                 this2=bpl2mod, k=(k&0xff)+fp_each;
  251.  
  252.             if(last1!=this1 || last2!=this2)
  253.                 CWAIT(ucoplist, j, 0);
  254.  
  255.             if(last1!=this1)
  256.             {
  257.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  258.                 last1=this1;
  259.             }
  260.  
  261.             if(last2!=this2)
  262.             {
  263.                 CMOVE(ucoplist, custom.bpl2mod, this2);
  264.                 last2=this2;
  265.             }
  266.         }
  267.     } else {
  268.  
  269.         /*
  270.          *  No scan-doubling possible; most probably because of a pal/ntsc screen 
  271.          *  and no V40 graphics library available.
  272.          */
  273.  
  274.         bpl1mod -= screen->RastPort.BitMap->BytesPerRow;
  275.  
  276.         fp_each = (y<<8) / (short)h;
  277.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  278.         {
  279.  
  280.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  281.                 this1=bpl1mod;
  282.             else                        /* finally, we are ready; next one */
  283.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  284.  
  285.             if(last1!=this1)
  286.             {
  287.                 CWAIT(ucoplist, j, 0);
  288.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  289.                 CMOVE(ucoplist, custom.bpl2mod, this1);
  290.                 last1=this1;
  291.             }
  292.         }
  293.  
  294.     }
  295.  
  296.     /*
  297.      *  Pretty nifty, isn't it? Finally, even a little bit copper-list-optimizing is build in!
  298.      */
  299.  
  300.     CEND(ucoplist);
  301.  
  302.     /* Set the freshly created user copper list */
  303.     Forbid();
  304.     screen->ViewPort.UCopIns = ucoplist;
  305.     Permit();
  306.  
  307.     /*  Enable user copper list clipping for this ViewPort.  */
  308.     (void) VideoControl( screen->ViewPort.ColorMap, uCopTags );
  309.  
  310.     RethinkDisplay();
  311.     WaitTOF();
  312.  
  313. }
  314.  
  315.  
  316.  
  317. /*
  318.  *--------------------------------------------------------------
  319.  *
  320.  * InitGrayDisplay --
  321.  *
  322.  *    Initialized display for gray scale dither.
  323.  *
  324.  * Results:
  325.  *      None.
  326.  *
  327.  * Side effects:
  328.  *      None.
  329.  *
  330.  *--------------------------------------------------------------
  331.  */
  332.  
  333. #define NUM_COLORS 128
  334.  
  335. void InitGrayDisplay(char *name)
  336. {
  337.     Quit("Not implemented, yet.\n", 0);
  338.  
  339.     DoDitherImage = GrayDitherImage;
  340. }
  341.  
  342.  
  343.  
  344.